#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
请求服务
"""

import logging
import json
import aiohttp
import asyncio
import time
from datetime import datetime
from bson import ObjectId
from db.mongo import get_db
from base.models.request import RequestDefinitionModel

logger = logging.getLogger(__name__)

class RequestService:
    """请求服务"""

    @staticmethod
    def create_request_definition(name, request_method, request_url, description=None, request_headers=None, request_body=None):
        """
        创建请求定义

        Args:
            name: 请求名称
            request_method: 请求方法
            request_url: 请求URL
            description: 请求描述
            request_headers: 请求头
            request_body: 请求体

        Returns:
            str: 请求定义ID
        """
        db = get_db()

        # 创建请求定义
        definition = RequestDefinitionModel(
            name=name,
            description=description,
            request_method=request_method,
            request_url=request_url,
            request_headers=request_headers,
            request_body=request_body
        )
        definition_dict = definition.to_dict()

        # 插入请求定义
        db.request_definitions.insert_one(definition_dict)
        definition_id = definition_dict["_id"]

        return definition_id

    @staticmethod
    def get_request_definitions(page=1, page_size=10):
        """
        获取请求定义列表

        Args:
            page: 页码
            page_size: 每页大小

        Returns:
            dict: 包含请求定义列表和总数的字典
        """
        db = get_db()

        # 计算跳过的记录数
        skip = (page - 1) * page_size

        # 查询请求定义
        definitions = list(db.request_definitions.find().sort("created_at", -1).skip(skip).limit(page_size))

        # 获取总记录数
        total = db.request_definitions.count_documents({})

        return {
            "definitions": definitions,
            "total": total,
            "page": page,
            "page_size": page_size,
            "pages": (total + page_size - 1) // page_size
        }

    @staticmethod
    def get_request_definition_by_id(definition_id):
        """
        根据ID获取请求定义

        Args:
            definition_id: 请求定义ID

        Returns:
            dict: 请求定义详情
        """
        db = get_db()

        # 查询请求定义
        definition = db.request_definitions.find_one({"_id": definition_id})
        if not definition:
            return None

        return definition

    @staticmethod
    def update_request_definition(definition_id, name=None, description=None, request_method=None, 
                                 request_url=None, request_headers=None, request_body=None):
        """
        更新请求定义

        Args:
            definition_id: 请求定义ID
            name: 请求名称
            description: 请求描述
            request_method: 请求方法
            request_url: 请求URL
            request_headers: 请求头
            request_body: 请求体

        Returns:
            bool: 是否成功更新
        """
        db = get_db()

        # 查询请求定义
        definition = db.request_definitions.find_one({"_id": definition_id})
        if not definition:
            return False

        # 准备更新数据
        update_data = {"updated_at": datetime.utcnow()}
        if name is not None:
            update_data["name"] = name
        if description is not None:
            update_data["description"] = description
        if request_method is not None:
            update_data["request_method"] = request_method
        if request_url is not None:
            update_data["request_url"] = request_url
        if request_headers is not None:
            update_data["request_headers"] = request_headers
        if request_body is not None:
            update_data["request_body"] = request_body

        # 更新请求定义
        db.request_definitions.update_one({"_id": definition_id}, {"$set": update_data})

        return True

    @staticmethod
    def delete_request_definition(definition_id):
        """
        删除请求定义

        Args:
            definition_id: 请求定义ID

        Returns:
            bool: 是否成功删除
        """
        db = get_db()

        # 查询请求定义
        definition = db.request_definitions.find_one({"_id": definition_id})
        if not definition:
            return False

        # 删除请求定义
        db.request_definitions.delete_one({"_id": definition_id})

        return True

    @staticmethod
    async def execute_request(definition_id):
        """
        执行请求

        Args:
            definition_id: 请求定义ID

        Returns:
            dict: 请求执行结果
        """
        db = get_db()

        # 查询请求定义
        definition_dict = db.request_definitions.find_one({"_id": definition_id})
        if not definition_dict:
            return None

        # 转换为请求定义对象
        definition = RequestDefinitionModel.from_dict(definition_dict)

        # 执行请求
        method = definition.request_method
        url = definition.request_url
        headers = definition.request_headers
        body = definition.request_body

        start_time = time.time()

        try:
            async with aiohttp.ClientSession() as session:
                method_func = getattr(session, method.lower())
                async with method_func(
                    url,
                    headers=headers,
                    data=body,
                    ssl=False,
                    timeout=aiohttp.ClientTimeout(total=30)
                ) as response:
                    response_body = await response.text()
                    response_status = response.status
                    response_headers = dict(response.headers)
        except Exception as e:
            end_time = time.time()
            duration_ms = int((end_time - start_time) * 1000)
            
            return {
                "request": {
                    "method": method,
                    "url": url,
                    "headers": headers,
                    "body": body
                },
                "error": str(e),
                "duration_ms": duration_ms
            }

        end_time = time.time()
        duration_ms = int((end_time - start_time) * 1000)

        return {
            "request": {
                "method": method,
                "url": url,
                "headers": headers,
                "body": body
            },
            "response": {
                "status": response_status,
                "headers": response_headers,
                "body": response_body
            },
            "duration_ms": duration_ms
        }

    @staticmethod
    def execute_request_sync(definition_id):
        """
        同步执行请求（包装异步方法）

        Args:
            definition_id: 请求定义ID

        Returns:
            dict: 请求执行结果
        """
        loop = asyncio.new_event_loop()
        asyncio.set_event_loop(loop)
        try:
            result = loop.run_until_complete(RequestService.execute_request(definition_id))
            return result
        finally:
            loop.close()
